package com.study.mybatis.session;

import com.study.mybatis.binding.MapperRegistry;
import com.study.mybatis.executor.Executor;
import com.study.mybatis.executor.parameter.ParameterHandler;
import com.study.mybatis.executor.parameter.defaults.DefaultParameterHandler;
import com.study.mybatis.executor.resultset.ResultSetHandler;
import com.study.mybatis.executor.resultset.defaults.DefaultResultSetHandler;
import com.study.mybatis.executor.statement.PreparedStatementHandler;
import com.study.mybatis.executor.statement.StatementHandler;
import com.study.mybatis.mapping.MappedStatement;
import com.study.mybatis.plugins.InterceptorChain;
import com.study.mybatis.type.TypeHandlerRegistry;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yuantongqin
 * 2021/7/31
 * 所有的配置文件都保存在这里，包括xml中配置
 **/
public class Configuration {

    private Properties config = new Properties();

    private Map<String,MappedStatement> mappedList = new ConcurrentHashMap<>();
    TypeHandlerRegistry typeHandlerRegistry = null;
    private MapperRegistry mapperRegistry = new MapperRegistry(this);
    protected final InterceptorChain interceptorChain = new InterceptorChain();

    /**
     * 添加mapperStatement对象
     * @param id
     * @param mappedStatement
     */
    public void addMapped(String id,MappedStatement mappedStatement){
        mappedList.put(id,mappedStatement);
    }

    public MappedStatement getMapper(String id){
        return mappedList.get(id);
    }

    public TypeHandlerRegistry getTypeHandlerRegistry(){
        return typeHandlerRegistry;
    }

    public Properties getConfig() {
        return config;
    }

    public void setConfig(Properties config) {
        this.config = config;
    }

    public <T> void addMapperProxy(Class<T> tClass){
        this.mapperRegistry.addMapperProxy(tClass);
    }

    public MapperRegistry getMapperRegistry() {
        return mapperRegistry;
    }

    public void setMapperRegistry(MapperRegistry mapperRegistry) {
        this.mapperRegistry = mapperRegistry;
    }

    public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject,ResultHandler resultHandler) {
        StatementHandler statementHandler = new PreparedStatementHandler(executor, mappedStatement, parameterObject, resultHandler);
        statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
        return statementHandler;
    }

    public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject) {
        ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement,parameterObject);
        return parameterHandler;
    }

    public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler resultHandler) {
        ResultSetHandler resultSetHandler = new DefaultResultSetHandler(mappedStatement);
        return resultSetHandler;
    }
}
